#include <iostream>
#include <sys/socket.h>
#include <unistd.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/poll.h>

using std::cout;
using std::endl;

#define CLIENT_SIZE 2
#define ERR_CHECK(var, val, msg)                    \
    if (var == val)                                 \
    {                                               \
        std::cout << "error: " << msg << std::endl; \
        exit(-1);                                   \
    }

void server()
{
    int sockFd = socket(AF_INET, SOCK_STREAM, 0);
    ERR_CHECK(sockFd, -1, "socket");

    sockaddr_in sAddr{};
    sAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    sAddr.sin_port = htons(12345);
    sAddr.sin_family = AF_INET;

    int ret = connect(sockFd, (sockaddr *)&sAddr, sizeof(sAddr));
    ERR_CHECK(ret, -1, "connect");

    pollfd client[CLIENT_SIZE];
    client[0].events = POLLIN;
    client[0].fd = sockFd;
    client[1].fd = fileno(stdin);
    client[1].events = POLLIN;

    char buf[1024];
    while (1)
    {
        int ret = poll(client, 2, -1);
        ERR_CHECK(ret, -1, "poll");

        if (client[0].revents & POLLIN)
        {
            memset(buf, 0, strlen(buf));
            read(client[0].fd, buf, sizeof(buf));
            cout << "ser: " << buf << endl;
        }
        if (client[1].revents & POLLIN)
        {
            memset(buf, 0, strlen(buf));
            read(client[1].fd, buf, sizeof(buf));

            cout << "------------------: " << buf << endl;

            int ret = write(client[0].fd, buf, strlen(buf));
            cout << "------------------: " << buf << endl;
            ERR_CHECK(ret, -1, "write");
        }
    }

    close(sockFd);
}

int main(int args, char *argv[])
{
    server();
    return 0;
}